const docItemRegex = /@(\w+):\s(\w+)(\s\|\s[^\s]+)?/g;

const appendComment = function appendComment(method, comment) {
  const c = comment.value;
  docItemRegex.lastIndex = 0;
  let matched;
  while (matched = docItemRegex.exec(c)) {
    const [ _, name, type, desc] = matched;
    const descStr = desc ? desc.replace(/^\s\|\s/, '') : '';
    if (name === 'return') {
      method.return = {
        type,
        desc: descStr,
      }
    } else {
      method.params.some((x) => {
        if (x.name === name) {
          x.type = type;
          x.desc = descStr;
          return true;
        }
      });
    }
  }
};

const ps = {
  Program(node, env) {
    const classList = [];
    let item;
    for (item of node.body) {
      if (item.type === 'ClassDeclaration') {
        classList.push(ps.process(item, env));
      }
    }
    // 整合来自comment节点的文档
    env.comments.forEach((c) => {
      classList.some((cls) => {
        if (cls.start < c.start && cls.end > c.end) {
          let index = 0;
          const len = cls.methods.length
          const methods = cls.methods[0];
          while (index < len) {
            const method = cls.methods[index];
            if (method.start > c.start) break;
            index++;
          }
          const method = cls.methods[index];
          if (method) {
            method._start = c.start;
            appendComment(method, c);
          }
          
          return true;
        }
      });
    });
    // 区分constructor
    classList.forEach((cls) => {
      const method = cls.methods[index];
      let index = -1;
      cls.methods.some((x, i) => {
        if (x.name === 'constructor') {
          index = i;
          return true
        }
      });
      if (index !== -1) cls.cons = cls.methods.splice(index , 1)[0];
    });
    return classList;
  },
  ClassDeclaration(node, env) {
    return {
      start: node.start,
      end: node.end,
      name: node.id.name,
      superClass: node.superClass && node.superClass.name,
      methods: node.body.body.filter(x => x.type === 'MethodDefinition').map(item => ps.process(item, env)),
    };
  },
  MethodDefinition(node, env) {
    return {
      start: node.start,
      end: node.end,
      name: node.key.name,
      params: node.value.params.map((x) => {
        return {
          name: x.name,
        };
      }),
    };
  },
  process(node, env) {
    const p = ps[node.type];
    if (!p) {
      console.error('未处理的类型', node.type, node);
      return;
    }
    const result = p(node, env);
    return result;
  },
};

export default ps;
